import math
import numpy as np

# 1. 读取数据
def load_data(file_path):
    data = []
    labels = []
    with open(file_path, 'r') as f:
        for line in f.readlines():
            items = line.strip().split(',')
            if len(items) == 5:  # 确保每行有5项数据（4个特征+1个标签）
                # 将前4项作为特征，并转换为浮动类型
                data.append([float(i) for i in items[:-1]])
                # 将最后1项作为标签
                labels.append(items[-1])
    return np.array(data), np.array(labels)


# 2. 计算每个类别的先验概率
def calculate_prior_probabilities(labels):
    classes = np.unique(labels)
    prior_probabilities = {}
    for c in classes:
        prior_probabilities[c] = np.sum(labels == c) / len(labels)
    return prior_probabilities

# 3. 计算每个类别下每个特征的条件概率（假设特征符合高斯分布）
def calculate_conditional_probabilities(data, labels):
    classes = np.unique(labels)
    conditional_probabilities = {}
    for c in classes:
        # 获取类别为c的所有样本
        class_data = data[labels == c]
        mean = np.mean(class_data, axis=0)  # 每个特征的均值
        var = np.var(class_data, axis=0)  # 每个特征的方差
        conditional_probabilities[c] = {'mean': mean, 'var': var}
    return conditional_probabilities

# 4. 计算高斯分布的概率密度函数
def gaussian_probability(x, mean, var):
    # 高斯分布的概率密度函数
    epsilon = 1e-4  # 避免方差为0
    return (1.0 / math.sqrt(2.0 * math.pi * var + epsilon)) * math.exp(-((x - mean) ** 2) / (2.0 * var + epsilon))

# 5. 计算后验概率并进行分类预测
def predict(data, prior_probabilities, conditional_probabilities):
    predictions = []
    for sample in data:
        class_probabilities = {}
        for c, prior in prior_probabilities.items():
            # 计算每个类别的后验概率：P(class|data) ∝ P(data|class) * P(class)
            prob = math.log(prior)  # P(class)
            for i, x in enumerate(sample):
                mean = conditional_probabilities[c]['mean'][i]
                var = conditional_probabilities[c]['var'][i]
                prob += math.log(gaussian_probability(x, mean, var))  # P(data|class)
            class_probabilities[c] = prob
        # 选择具有最大后验概率的类别
        predicted_class = max(class_probabilities, key=class_probabilities.get)
        predictions.append(predicted_class)
    return np.array(predictions)

# 6. 评估模型的准确率
def accuracy(predictions, labels):
    return np.mean(predictions == labels)

# 主要流程
if __name__ == "__main__":
    # 读取数据
    file_path = 'C:\\Users\\li\\Desktop\\机器学习\\iris\\iris.data'
    data, labels = load_data(file_path)

    # 计算先验概率和条件概率
    prior_probabilities = calculate_prior_probabilities(labels)
    conditional_probabilities = calculate_conditional_probabilities(data, labels)

    # 预测（使用全部数据作为测试数据）
    predictions = predict(data, prior_probabilities, conditional_probabilities)

    # 输出准确率
    acc = accuracy(predictions, labels)
    print(f"模型的准确率是: {acc * 100:.2f}%")